package control;

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import model.objects.GameObject;
import physics.movement.HeroMovementStrategy;
import util.Constants;


public class InputManager {
    private JComponent myJComponent;

    public InputManager (JComponent component) {
        myJComponent = component;
        
        // TODO: make this take a file - read in based on a keyconfig file
        initTriggers();
        
        @SuppressWarnings("serial")
        Action print1 = new AbstractAction() {
            public void actionPerformed (ActionEvent arg0) {
                System.out.println("LeftPressed!");
            }
        };
        addAction(Constants.Events.LEFT + Constants.Events.PRESSED, print1);
        
    }
    
    public void addAction (String triggerName, Action action) {
        myJComponent.getActionMap().put(triggerName, action);
    }

    private void initTriggers () {
        addBipartiteTrigger(KeyEvent.VK_W, Constants.Events.UP);
        addBipartiteTrigger(KeyEvent.VK_A, Constants.Events.LEFT);
        addBipartiteTrigger(KeyEvent.VK_S, Constants.Events.DOWN);
        addBipartiteTrigger(KeyEvent.VK_D, Constants.Events.RIGHT);
    }
    
    private void addBipartiteTrigger (int keyCode, String triggerName) {
        addTrigger(keyCode, triggerName + Constants.Events.PRESSED, false);
        addTrigger(keyCode, triggerName + Constants.Events.RELEASED, true);
    }
    
    private void addTrigger (int keyCode, String triggerName, boolean onRelease) {
        myJComponent.getInputMap().put(KeyStroke.getKeyStroke(
            keyCode, 0, onRelease), triggerName);
    }
    
    public void bindHeroAction (final GameObject hero) {
        final HeroMovementStrategy hms = (HeroMovementStrategy) hero.getMovementStrategy();
        
        @SuppressWarnings("serial")
        Action moveLeftOn = new AbstractAction() {
            public void actionPerformed (ActionEvent arg0) {
                hms.runLeft(hero);
            }
        };
        addAction(Constants.Events.LEFT + Constants.Events.PRESSED, moveLeftOn);
        
        @SuppressWarnings("serial")
        Action moveLeftOff = new AbstractAction() {
            public void actionPerformed (ActionEvent arg0) {
                hms.stopRunning(hero);
            }
        };
        addAction(Constants.Events.LEFT + Constants.Events.PRESSED, moveLeftOff);
        
        @SuppressWarnings("serial")
        Action moveRightOn = new AbstractAction() {
            public void actionPerformed (ActionEvent arg0) {
                hms.runRight(hero);
            }
        };
        addAction(Constants.Events.LEFT + Constants.Events.PRESSED, moveRightOn);
        
        @SuppressWarnings("serial")
        Action moveRightOff = new AbstractAction() {
            public void actionPerformed (ActionEvent arg0) {
                hms.stopRunning(hero);
            }
        };
        addAction(Constants.Events.LEFT + Constants.Events.PRESSED, moveRightOff);
        
        @SuppressWarnings("serial")
        Action jumpOn = new AbstractAction() {
            public void actionPerformed (ActionEvent arg0) {
                hms.jumpOn(hero);
            }
        };
        addAction(Constants.Events.LEFT + Constants.Events.PRESSED, jumpOn);
        
        @SuppressWarnings("serial")
        Action jumpOff = new AbstractAction() {
            public void actionPerformed (ActionEvent arg0) {
                hms.jumpOff(hero);
            }
        };
        addAction(Constants.Events.LEFT + Constants.Events.PRESSED, jumpOff);
    }
}
